﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Founder.PKURG.VisioReader;


namespace ToolForDataBaseCreate
{
    public partial class MainForm : Form
    {
        Founder.PKURG.CRM.CRMInfoOP op;
        public MainForm()
        {
            InitializeComponent();
            op = new Founder.PKURG.CRM.CRMInfoOP(ToolForDataBaseCreate.Properties.Settings.Default.ConnectingString);

            TBUrl.Text = op.connect.ConfigurationInfo.OrgServiceUri;

        }

        private void ButLoad_Click(object sender, EventArgs e)
        {
            OpenFileDialog dig = new OpenFileDialog();

            dig.Multiselect = false;
            dig.Filter = "visio xml|*.xml";
            if (dig.ShowDialog() == DialogResult.OK)
            {
                string filePath = dig.FileName;

                List<EntityInfo> infos = VisioXMLReader.GetEntites(filePath);

                infos = OrderCreateInfo(infos);

                CBTableList.Items.Clear();

                foreach (EntityInfo item in infos)
                {
                    CBTableList.Items.Add(item, true);
                }

            }
        }
        /// <summary>
        /// 根据调用关系排序
        /// </summary>
        /// <param name="infos"></param>
        /// <returns></returns>
        private List<EntityInfo> OrderCreateInfo(List<EntityInfo> infos)
        {
            List<EntityInfo> newInfos = new List<EntityInfo>();
            newInfos.AddRange(infos.FindAll(x => x.PropList.FindAll(y => y.ForeignKeyInfo != null).Count == 0));

            List<EntityInfo> fInfos = infos.FindAll(x => !(newInfos.Contains(x)));
            List<EntityInfo> linkList = new List<EntityInfo>();
            foreach (EntityInfo item in fInfos)
            {
                Stack<EntityInfo> parentStack = new Stack<EntityInfo>();

                AddInfoToOrderQueue(linkList, item, parentStack);

            }
            newInfos.AddRange(linkList.FindAll(x => !newInfos.Contains(x)));
            return newInfos;
        }

        private static void AddInfoToOrderQueue(List<EntityInfo> linkList, EntityInfo item, Stack<EntityInfo> parentStack)
        {
            //不支持相互关联表结构
            if (parentStack.Contains(item))
            {
                throw new Exception("存在相互关联结构");
            }

            if (!linkList.Contains(item))
            {
                foreach (PropInfo pItem in item.PropList)
                {
                    if (pItem.ForeignKeyInfo != null)
                    {
                        //if (!linkList.Contains(pItem.ForeignKeyInfo.Info.BelongInfo))
                        //{
                        parentStack.Push(item);
                        AddInfoToOrderQueue(linkList, pItem.ForeignKeyInfo.Info.BelongInfo, parentStack);
                        parentStack.Pop();
                        //}
                    }
                }

                linkList.Add(item);
            }
        }

        private void ButCreate_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(TBPre.Text))
            {
                MessageBox.Show("请输入前缀", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            op.Prefix = TBPre.Text.ToLower();
            foreach (EntityInfo item in CBTableList.CheckedItems)
            {
                CreateEntity(item);
            }
            MessageBox.Show("创建完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void CreateEntity(EntityInfo item)
        {
            op.CreateEntity(new Founder.PKURG.CRM.EntityInfo()
            {
                DisplayName = item.PhysicalName,
                SchemaName = item.ConceptualName
            });

            foreach (PropInfo pInfo in item.PropList)
            {
                if (pInfo.PhysicalName.ToLower() == "id")
                {
                    continue;
                }

                if (pInfo.Datatype == PhysicalDatatype._GUID)
                {
                    op.CreateEntityLookField(item.ConceptualName, pInfo.ForeignKeyInfo.Info.BelongInfo.ConceptualName,
                        pInfo.ForeignKeyInfo.Info.ConceptualName, new Founder.PKURG.CRM.EntityInfoField()
                    {
                        DisplayName = pInfo.PhysicalName,
                        SchemaName = pInfo.ConceptualName,
                    });
                }
                else
                {
                    op.CreateEntityFields(item.ConceptualName, new Founder.PKURG.CRM.EntityInfoField()
                    {
                        DisplayName = pInfo.PhysicalName,
                        SchemaName = pInfo.ConceptualName,
                        FType = GetFType(pInfo.Datatype)
                    });
                }
            }
        }

        private Founder.PKURG.CRM.EntityInfoFieldType GetFType(PhysicalDatatype physicalDatatype)
        {
            Founder.PKURG.CRM.EntityInfoFieldType type = Founder.PKURG.CRM.EntityInfoFieldType.TextType;
            switch (physicalDatatype)
            {
                case PhysicalDatatype._VARCHAR:

                    break;
                case PhysicalDatatype._DATETIME:
                    type = Founder.PKURG.CRM.EntityInfoFieldType.DateTimeType;
                    break;
                case PhysicalDatatype._GUID:
                    type = Founder.PKURG.CRM.EntityInfoFieldType.GuidType;
                    break;
                case PhysicalDatatype._INTEGER:
                    type = Founder.PKURG.CRM.EntityInfoFieldType.IntType;
                    break;
                case PhysicalDatatype._FLOAT:
                    type = Founder.PKURG.CRM.EntityInfoFieldType.FloatType;
                    break;
                default:
                    break;
            }

            return type;
        }
    }
}
